import axios from "axios";
import type {
  InternalAxiosRequestConfig,
  AxiosInstance,
  AxiosResponse,
  AxiosRequestConfig,
  Canceler,
} from "axios";
import { message } from "antd";

declare module "axios" {
  export interface AxiosRequestConfig {
    silent?: boolean;
  }
}

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: "/api", // 可根据实际情况调整
  timeout: 10000,
  headers: {
    "Content-Type": "application/json",
  },
});

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 自动携带 token
    const token = localStorage.getItem("token");
    if (token && config.headers) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 统一处理业务错误
    const { data, config } = response as AxiosResponse & {
      config: { silent?: boolean };
    };
    if (data && data.code && data.code !== 0) {
      if (!config.silent) {
        message.error(data.msg || "请求失败");
      }
      return Promise.reject(data);
    }
    return data;
  },
  (error) => {
    // 统一处理 HTTP 错误
    const config = (error.config || {}) as { silent?: boolean };
    if (!config.silent) {
      if (error.response) {
        message.error(
          error.response.data?.msg || `请求错误: ${error.response.status}`
        );
      } else {
        message.error(error.message || "网络异常");
      }
    }
    return Promise.reject(error);
  }
);

// ========== 扩展功能 ==========

// 1. 自定义 header 请求
export function requestWithHeaders(
  config: AxiosRequestConfig & { headers?: Record<string, unknown> }
) {
  return service({ ...config });
}

// 2. 取消请求
export function getCancelToken() {
  const CancelToken = axios.CancelToken;
  let cancel: Canceler | undefined;
  const token = new CancelToken(function executor(c) {
    cancel = c;
  });
  return { cancel: cancel!, token };
}

// 3. 文件/图片上传
export function uploadFile(
  url: string,
  file: File | Blob,
  extraData?: Record<string, unknown>,
  config?: AxiosRequestConfig
) {
  const formData = new FormData();
  formData.append("file", file);
  if (extraData) {
    Object.keys(extraData).forEach((key) => {
      formData.append(key, extraData[key] as string | Blob);
    });
  }
  return service.post(url, formData, {
    headers: { "Content-Type": "multipart/form-data" },
    ...config,
  });
}

// 4. 文件下载（流式下载）
export function downloadFile(
  url: string,
  params?: unknown,
  config?: AxiosRequestConfig
) {
  return service.post(url, params, {
    responseType: "blob",
    ...config,
  });
}

// ========== 通用方法泛型封装 ==========

export function get<T = unknown>(
  url: string,
  params?: unknown,
  config?: AxiosRequestConfig
) {
  return service.get<T>(url, { params, ...config });
}

export function post<T = unknown>(
  url: string,
  data?: unknown,
  config?: AxiosRequestConfig
) {
  return service.post<T>(url, data, config);
}

export function del<T = unknown>(
  url: string,
  params?: unknown,
  config?: AxiosRequestConfig
) {
  return service.delete<T>(url, { params, ...config });
}

export function patch<T = unknown>(
  url: string,
  data?: unknown,
  config?: AxiosRequestConfig
) {
  return service.patch<T>(url, data, config);
}

export default service;
